﻿/************************************************************************

 This file is part of Chroma.

 EscapeFromPrisonPlanet is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 EscapeFromPrisonPlanet is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

************************************************************************/

// All code (c)2013 Scott Bevin. all rights reserved

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace LudumDare26.PrimitiveRendering
{
	public class PERectangle : PEPrimitive
	{
		public float Width;
		public float Height;

		public override int PrimitiveCount { get { return primitiveCount; } }

		private static Vector3[] tempArray1 = new Vector3[4];
		private static Vector3[] tempArray2 = new Vector3[4];

		private int primitiveCount = 0;

		private static Vector3[] rectangleIdentityCoords = new Vector3[] {
            new Vector3(0.0f, 0.0f, 0f),
            new Vector3(0.0f, 1.0f, 0f),
            new Vector3(1.0f, 1.0f, 0f),
            new Vector3(1.0f, 0.0f, 0f),
        };

		internal static Vector2[] texCoords = new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1) };

		public PERectangle()
		{
			Type = PEPrimitiveType.Rectangle;
		}

		public PERectangle(float width, float height)
		{
			Type = PEPrimitiveType.Rectangle;
			Width = width;
			Height = height;
			BorderColor = Color.White;
			BorderWidth = 1.0f;
			BorderColor = Color.Black;
		}

		public PERectangle(float width, float height, float layer, Color color)
		{
			Type = PEPrimitiveType.Rectangle;
			Width = width;
			Height = height;
			Layer = layer;
			FillColor = color;
			IsFilled = true;
			BorderWidth = 1.0f;
			BorderColor = Color.Black;
		}

		public override bool Intersection(PEPrimitive primitive)
		{
			throw new NotImplementedException();
		}

		public override bool Inside(Microsoft.Xna.Framework.Vector2 point)
		{
			throw new NotImplementedException();
		}

		public override void CreateUV()
		{
			throw new NotImplementedException();
		}

		public override void Draw(ref VertexPositionColorTexture[] vertices, ref int vertexIndex, ref short[] indices, ref int indiceIndex)
		{
			int tempIndex = vertexIndex;
			primitiveCount = 0;

			Matrix mat = Matrix.CreateScale(Width - BorderWidth * 2, Height - BorderWidth * 2, 1f) * Matrix.CreateRotationZ(Rotation) * Matrix.CreateTranslation(new Vector3(Position, -Layer));

			Vector3.Transform(rectangleIdentityCoords, ref mat, tempArray2);

			if (IsFilled)
			{
				vertices[vertexIndex].Position = tempArray2[0];
				vertices[vertexIndex].Color = FillColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[0];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray2[1];
				vertices[vertexIndex].Color = FillColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[1];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray2[2];
				vertices[vertexIndex].Color = FillColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[2];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray2[3];
				vertices[vertexIndex].Color = FillColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[3];
				vertexIndex++;

				// create the indices
				indices[indiceIndex + 0] = (short)(tempIndex + 2);
				indices[indiceIndex + 1] = (short)(tempIndex + 1);
				indices[indiceIndex + 2] = (short)(tempIndex + 0);
				indices[indiceIndex + 3] = (short)(tempIndex + 3);
				indices[indiceIndex + 4] = (short)(tempIndex + 2);
				indices[indiceIndex + 5] = (short)(tempIndex + 0);
				indiceIndex += 6;

				primitiveCount += 2;

				// reset index
				tempIndex = vertexIndex;
			}

			if (BorderWidth > 0)
			{
				mat = Matrix.CreateScale(Width, Height, 1f) * Matrix.CreateRotationZ(Rotation) * Matrix.CreateTranslation(new Vector3(Position, -Layer));

				Vector3.Transform(rectangleIdentityCoords, ref mat, tempArray1);

				// scale the normal by half the lines width and translate to the start and end of the line
				vertices[vertexIndex].Position = tempArray1[0];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[0];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray1[1];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[1];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray1[2];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[2];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray1[3];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[3];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray2[0];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[0];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray2[1];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[1];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray2[2];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[2];
				vertexIndex++;
				vertices[vertexIndex].Position = tempArray2[3];
				vertices[vertexIndex].Color = BorderColor;
				vertices[vertexIndex].TextureCoordinate = texCoords[3];
				vertexIndex++;

				indices[indiceIndex + 0] = (short)(tempIndex + 0);
				indices[indiceIndex + 1] = (short)(tempIndex + 1);
				indices[indiceIndex + 2] = (short)(tempIndex + 5);
				indices[indiceIndex + 3] = (short)(tempIndex + 0);
				indices[indiceIndex + 4] = (short)(tempIndex + 5);
				indices[indiceIndex + 5] = (short)(tempIndex + 4);
				indiceIndex += 6;

				indices[indiceIndex + 0] = (short)(tempIndex + 1);
				indices[indiceIndex + 1] = (short)(tempIndex + 2);
				indices[indiceIndex + 2] = (short)(tempIndex + 5);
				indices[indiceIndex + 3] = (short)(tempIndex + 2);
				indices[indiceIndex + 4] = (short)(tempIndex + 6);
				indices[indiceIndex + 5] = (short)(tempIndex + 5);
				indiceIndex += 6;

				indices[indiceIndex + 0] = (short)(tempIndex + 2);
				indices[indiceIndex + 1] = (short)(tempIndex + 7);
				indices[indiceIndex + 2] = (short)(tempIndex + 3);
				indices[indiceIndex + 3] = (short)(tempIndex + 2);
				indices[indiceIndex + 4] = (short)(tempIndex + 6);
				indices[indiceIndex + 5] = (short)(tempIndex + 7);
				indiceIndex += 6;

				indices[indiceIndex + 0] = (short)(tempIndex + 7);
				indices[indiceIndex + 1] = (short)(tempIndex + 3);
				indices[indiceIndex + 2] = (short)(tempIndex + 0);
				indices[indiceIndex + 3] = (short)(tempIndex + 0);
				indices[indiceIndex + 4] = (short)(tempIndex + 4);
				indices[indiceIndex + 5] = (short)(tempIndex + 7);
				indiceIndex += 6;

				primitiveCount += 8;
			}
		}
	}
}